From 6dec681bb6a8c98aeea38ccc02aee239ecf39a42 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 5 Feb 2009 12:09:10 +0000 Subject: [PATCH] Add a page_info flag to indicate whether free pages need a TLB flush on next use. Apart from teh small performance gain of this, my primary motivation is to avoid TLB flushes very early in boot, when the system is not yet properly set up for cross-TLB shootdowns. Signed-off-by: Keir Fraser --- xen/common/page_alloc.c | 16 ++++++++++------ xen/include/asm-ia64/mm.h | 2 ++ xen/include/asm-x86/mm.h | 6 ++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index de99f7333b..3c84fd638a 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -399,10 +399,13 @@ static struct page_info *alloc_heap_pages( /* Reference count must continuously be zero for free pages. */ BUG_ON(pg[i].count_info != 0); - /* Add in any extra CPUs that need flushing because of this page. */ - cpus_andnot(extra_cpus_mask, cpu_online_map, mask); - tlbflush_filter(extra_cpus_mask, pg[i].tlbflush_timestamp); - cpus_or(mask, mask, extra_cpus_mask); + if ( pg[i].u.free.need_tlbflush ) + { + /* Add in extra CPUs that need flushing because of this page. */ + cpus_andnot(extra_cpus_mask, cpu_online_map, mask); + tlbflush_filter(extra_cpus_mask, pg[i].tlbflush_timestamp); + cpus_or(mask, mask, extra_cpus_mask); + } /* Initialise fields which have other uses for free pages. */ pg[i].u.inuse.type_info = 0; @@ -446,8 +449,9 @@ static void free_heap_pages( pg[i].count_info = 0; /* If a page has no owner it will need no safety TLB flush. */ - pg[i].tlbflush_timestamp = - page_get_owner(&pg[i]) ? tlbflush_current_time() : 0; + pg[i].u.free.need_tlbflush = (page_get_owner(&pg[i]) != NULL); + if ( pg[i].u.free.need_tlbflush ) + pg[i].tlbflush_timestamp = tlbflush_current_time(); } spin_lock(&heap_lock); diff --git a/xen/include/asm-ia64/mm.h b/xen/include/asm-ia64/mm.h index d28aa565dc..5d35304f7d 100644 --- a/xen/include/asm-ia64/mm.h +++ b/xen/include/asm-ia64/mm.h @@ -62,6 +62,8 @@ struct page_info struct { /* Order-size of the free chunk this page is the head of. */ u32 order; + /* Do TLBs need flushing for safety before next page use? */ + bool_t need_tlbflush; } free; } u; diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 4a8c37f96a..8c1c675ebf 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -66,6 +66,12 @@ struct page_info unsigned long count:26; /* Reference count */ } sh; + /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */ + struct { + /* Do TLBs need flushing for safety before next page use? */ + bool_t need_tlbflush; + } free; + } u; union { -- 2.30.2